package fasdk

import (
	"gitee.com/bupt-zkjc/fabric2.2-interface/common/log"
	"gitee.com/bupt-zkjc/fabric2.2-interface/config_yaml"
	"gitee.com/bupt-zkjc/fabric2.2-interface/constant"
	"fmt"
	"gitee.com/bupt-zkjc/fabric-sdk-go/pkg/client/resmgmt"
	"gitee.com/bupt-zkjc/fabric-sdk-go/pkg/common/errors/retry"
	"gitee.com/bupt-zkjc/fabric-sdk-go/pkg/core/config"
	"gitee.com/bupt-zkjc/fabric-sdk-go/pkg/fabsdk"
	"path/filepath"
)

var logger = log.GetLogger("fasdk", log.ERROR)

const (
	Admin = "Admin"
	User  = "User1"
)

type FabricClient struct {
	ChainName      string
	OrdererDomain  string
	Orgs           []string
	//EndorserOrgs   []string
	OrgAdmin       string
	UserName       string
	ChannelId      string
	GoPath         string

	resmgmtClients []*resmgmt.Client      //当前需要操作的组织，不一定是所有组织
	sdk            *fabsdk.FabricSDK
	retry          resmgmt.RequestOption
	orderer        resmgmt.RequestOption
}

func (f *FabricClient) Setup() error {
	//path, err := config_yaml.GetCurrentPath()
	//if err != nil{
	//	return err
	//}
	parentPath, err := config_yaml.GetParentDirectory()
	if err != nil{
		return err
	}
	configFile := filepath.Join(parentPath, constant.Dirpath, "config_" + f.ChainName + constant.Yaml)
	fmt.Println(configFile)
	sdk, err := fabsdk.New(config.FromFile(configFile))
	if err != nil {
		logger.Error("failed to create SDK")
		return err
	}
	f.sdk = sdk
	resmgmtClients := make([]*resmgmt.Client, 0)
	for _, v := range f.Orgs {
		resmgmtClient, err := resmgmt.New(sdk.Context(fabsdk.WithUser(f.OrgAdmin), fabsdk.WithOrg(v)))
		if err != nil {
			logger.Errorf("Failed to create channel management client: %s", err)
			return err
		}
		resmgmtClients = append(resmgmtClients, resmgmtClient)
	}
	f.resmgmtClients = resmgmtClients

	f.retry = resmgmt.WithRetry(retry.DefaultResMgmtOpts)
	f.orderer = resmgmt.WithOrdererEndpoint(f.OrdererDomain)

	return nil
}

func (f *FabricClient) Close() {
	if f.sdk != nil {
		f.sdk.Close()
	}
}

func NewFabricClient(chainName string, channelName string, orgs []string, orderer string, chaincodeSourcePath string) *FabricClient {
	fabric := &FabricClient{
		ChainName:      chainName,
		ChannelId:      channelName,
		OrdererDomain:  orderer,
		Orgs:           orgs,
		//EndorserOrgs:   endorserOrgs,
		OrgAdmin:       Admin,
		UserName:       User,
		GoPath:         chaincodeSourcePath,
	}

	return fabric

}